package org.balthie.demo.jdk.nio.reactor.singleThread;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;

class Reactor implements Runnable {
	final Selector selector;
	final ServerSocketChannel serverSocket;
	
	Reactor(int port) throws IOException { // Reactor初始化
		selector = Selector.open();
		serverSocket = ServerSocketChannel.open();
		serverSocket.socket().bind(new InetSocketAddress(port));
		// 非阻塞
		serverSocket.configureBlocking(false);
		// 分步处理,第一步, 注册accept事件（客户端3次握手）
		SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
		// attach callback object, Acceptor
		sk.attach(new Acceptor(selector, serverSocket));
	}

	public void run() {
		try {
			while (!Thread.interrupted()) {
				// reactor线程堵塞在select方法中，直到有io事件发送			
				selector.select();
				Set selected = selector.selectedKeys();
				Iterator it = selected.iterator();
				while (it.hasNext()) {
					// Reactor负责dispatch收到的事件
					dispatch((SelectionKey) (it.next()));
				}
				selected.clear();
			}
		} catch (IOException ex) {
			/* ... */ }
	}

	void dispatch(SelectionKey k) {
		Runnable r = (Runnable) (k.attachment());
		// 调用之前注册的callback对象
		if (r != null) {
			r.run();
		}
	}

	// inner class
//	class Acceptor implements Runnable {
//		public void run() {
//			try {
//				SocketChannel channel = serverSocket.accept();
//				if (channel != null)
//					new Handler(selector, channel);
//			} catch (IOException ex) {
//				/* ... */ }
//		}
//	}
}